// DelegateTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <cassert>

#include <tutil/delegate/delegate.hxx>

static void StaticFunc(const char* s)
{
   printf("  Static function invoked by %s\n", s);
}

class MyObject
{
public:
   int count;
   MyObject(int n) : count(n) { }

   void memberFunc1(const char* s)
   {
      printf("  Member function invoked by %s\n", s);
      this->count++;
   }

   void memberFunc2(const char* s, int n)
   {
      printf("  Member function invoke by %s, with param n[%d]", s, n);
   }
};

class MyFunctor
{
public:
   void operator()(const char* s)
   {
      printf("  Functor invoked by %s\n", s);
   }
};

using namespace TUtil;
#ifdef _WIN32
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
   // Create delegate a that references a static function:
   Delegate<void (const char*), TUtil::PolicyMultiThreaded> a;
   //Delegate<void (const char*), PolicySingleThreaded> a(&StaticFunc);
   a += &StaticFunc;
   //assert(a == &StaticFunc);
   assert(!(a != &StaticFunc));

   printf("Invoking delegate a:\n");
   a("a");
   printf("\n");

   // Create delegate b that references an instance function:
   MyObject myObj(0);
   Delegate<void (const char*)> b(&myObj, &MyObject::memberFunc1);
   b += std::make_pair(&myObj, &MyObject::memberFunc1);
   assert(b == std::make_pair(&myObj, &MyObject::memberFunc1));

   printf("Invoking delegate b:\n");
   b("b");
   assert(myObj.count == 1);
   printf("\n");

   // Create delegate c that references a function object:
#if ENABLE_FUNCTOR
   MyFunctor myFunctor;
   Delegate<void (const char*)> c;
   c += myFunctor;

   printf("Invoking delegate c:\n");
   c("c");
   printf("\n");
#endif

   // Add an instance function and a functor to delegate a
   a += std::make_pair(&myObj, &MyObject::memberFunc1);
   //a += myFunctor;

   printf("Invoking delegate a:\n");
   a("a");
   assert(myObj.count == 2);
   printf("\n");

   // Remove the static function from delegate a
   a -= &StaticFunc;
   printf("Invoking delegate a:\n");
   a("a");
   assert(myObj.count == 3);
   printf("\n");

   // Create delegate d from a
   Delegate<void (const char*)> d(a);

   // Add delegate b to delegate d
   //d += Delegate<void (const char*)>(&StaticFunc);

   printf("Invoking delegate d:\n");
   d("d");
   assert(myObj.count == 4);
   printf("\n");

   a -= std::make_pair(&myObj, &MyObject::memberFunc1);
   printf("Invoking delegate a:\n");
   a("a");
   assert(myObj.count == 4);
   printf("\n");

   printf("Invoking delegate f:\n");
   Delegate<void (const char*, int)> f;
   f += std::make_pair(&myObj, &MyObject::memberFunc2);
   f("f", 0xff);
   printf("\n");

   getchar();

   return 0;
}


